package cn.iocoder.yudao.module.system.controller.admin.erp.warehouseinventory;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.controller.admin.erp.warehouseinventory.vo.WarehouseInventoryPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.erp.warehouseinventory.vo.WarehouseInventoryRespVO;
import cn.iocoder.yudao.module.system.controller.admin.erp.warehouseinventory.vo.WarehouseInventorySaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.erp.warehouseinventorysku.vo.WarehouseInventorySkuRespVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
import cn.iocoder.yudao.module.system.core.ErpOperationLog;
import cn.iocoder.yudao.module.system.dal.dataobject.erp.warehouse.WarehouseDO;
import cn.iocoder.yudao.module.system.dal.dataobject.erp.warehouseinventory.WarehouseInventoryDO;
import cn.iocoder.yudao.module.system.dal.dataobject.erp.warehouseinventorysku.WarehouseInventorySkuDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.framework.CommonConstant;
import cn.iocoder.yudao.module.system.service.erp.customermanage.CustomerManageService;
import cn.iocoder.yudao.module.system.service.erp.operatelog.ErpOperateLogService;
import cn.iocoder.yudao.module.system.service.erp.warehouse.WarehouseService;
import cn.iocoder.yudao.module.system.service.erp.warehouseinventory.WarehouseInventoryService;
import cn.iocoder.yudao.module.system.service.erp.warehouseinventorysku.WarehouseInventorySkuService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.constraints.*;
import jakarta.validation.*;
import jakarta.servlet.http.*;

import java.time.LocalDateTime;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exceptionErr;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static java.util.Arrays.asList;

@Tag(name = "管理后台 - 仓库库存")
@RestController
@RequestMapping("/erp/warehouse-inventory")
@Validated
public class WarehouseInventoryController {
    @Resource
    private AdminUserService userService;
    @Resource
    private CustomerManageService customerManageService;
    @Resource
    private WarehouseService warehouseService;
    @Resource
    private WarehouseInventoryService warehouseInventoryService;
    @Resource
    private WarehouseInventorySkuService warehouseInventorySkuService;
    @Resource
    private ErpOperateLogService erpOperateLogService;

    @PostMapping("/create")
    @Operation(summary = "创建仓库库存")
    @PreAuthorize("@ss.hasPermission('erp:warehouse-inventory:create')")
    public CommonResult<Long> createWarehouseInventory(@Valid @RequestBody WarehouseInventorySaveReqVO createReqVO) {
        return success(warehouseInventoryService.createWarehouseInventory(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新仓库库存")
    @PreAuthorize("@ss.hasPermission('erp:warehouse-inventory:update')")
    public CommonResult<Boolean> updateWarehouseInventory(@Valid @RequestBody WarehouseInventorySaveReqVO updateReqVO) {
        warehouseInventoryService.updateWarehouseInventory(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除仓库库存")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('erp:warehouse-inventory:delete')")
    public CommonResult<Boolean> deleteWarehouseInventory(@RequestParam("id") Long id) {
        warehouseInventoryService.deleteWarehouseInventory(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得仓库库存")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('erp:warehouse-inventory:query')")
    public CommonResult<WarehouseInventoryRespVO> getWarehouseInventory(@RequestParam("id") Long id) {
        WarehouseInventoryDO warehouseInventory = warehouseInventoryService.getWarehouseInventory(id);
        return success(BeanUtils.toBean(warehouseInventory, WarehouseInventoryRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得仓库库存分页")
    @PreAuthorize("@ss.hasPermission('erp:warehouse-inventory:query')")
    public CommonResult<PageResult<WarehouseInventoryRespVO>> getWarehouseInventoryPage(@Valid WarehouseInventoryPageReqVO pageReqVO) {
        Long loginUserId= SecurityFrameworkUtils.getLoginUserId();
        AdminUserDO user=userService.getUser(loginUserId);
        String roleCode=user.getRoleCode();
        PageResult<WarehouseInventoryRespVO> pageResult =new PageResult<>();
        if(ObjectUtil.equal(loginUserId,1L)||asList(CommonConstant.ERP_ADMIN,CommonConstant.ERP_SUPER_ADMIN).contains(roleCode)) {
            List<Long> customerIds = new ArrayList<>();
            if (ObjectUtil.contains(CommonConstant.ERP_ADMIN, roleCode)) {
                customerIds = customerManageService.getCustomerIds(loginUserId);
            }
            pageReqVO.setCustomerIds(customerIds);
        }
        pageResult=BeanUtils.toBean(warehouseInventoryService.getWarehouseInventoryPage(pageReqVO), WarehouseInventoryRespVO.class);
        pageResult.getList().forEach(e->{
            e.setWarehouse(warehouseService.getWarehouse(e.getWarehouseId()).getName());
            e.setCustomer(userService.getUser(e.getCustomerId()).getNickname());
            e.setSku(warehouseInventorySkuService.getWarehouseInventorySkuList(e.getWarehouseId(),e.getCustomerId()));
        });

        return success(pageResult);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出仓库库存 Excel")
    @PreAuthorize("@ss.hasPermission('erp:warehouse-inventory:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportWarehouseInventoryExcel(@Valid WarehouseInventoryPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        if(pageReqVO.getIds().isEmpty()){
            throw exceptionErr(500,"请选择导出数据");
        }
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        Long loginUserId= SecurityFrameworkUtils.getLoginUserId();
        AdminUserDO user=userService.getUser(loginUserId);
        String roleCode=user.getRoleCode();
        PageResult<WarehouseInventoryRespVO> pageResult =new PageResult<>();
        if(ObjectUtil.equal(loginUserId,1L)||asList(CommonConstant.ERP_ADMIN,CommonConstant.ERP_SUPER_ADMIN).contains(roleCode)) {
            List<Long> customerIds = new ArrayList<>();
            if (ObjectUtil.contains(CommonConstant.ERP_ADMIN, roleCode)) {
                customerIds = customerManageService.getCustomerIds(loginUserId);
            }
            pageReqVO.setCustomerIds(customerIds);
        }

        List<WarehouseInventoryDO>list=warehouseInventoryService.getWarehouseInventoryPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "仓库库存.xls", "数据", WarehouseInventoryRespVO.class,
                        BeanUtils.toBean(list, WarehouseInventoryRespVO.class));
    }


    @PutMapping("/inventory")
    @Operation(summary = "盘点仓库库存")
    @PreAuthorize("@ss.hasPermission('erp:warehouse-inventory:inventory')")
    @ErpOperationLog(module = "盘点",description = "盘点仓库库存")
    public CommonResult<Boolean> inventoryWarehouseInventory(@RequestBody WarehouseInventoryPageReqVO pageReqVO) {
        List<Long> ids = pageReqVO.getIds();
        LocalDateTime now = LocalDateTime.now();
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        ids.forEach(id->{
        WarehouseInventorySaveReqVO update = new WarehouseInventorySaveReqVO();
        update.setCheckBy(loginUserId);
        update.setCheckTime(now);
        update.setId(id);
        warehouseInventoryService.updateWarehouseInventory(update);
        WarehouseInventoryDO warehouseInventory = warehouseInventoryService.getWarehouseInventory(id);
        Long warehouseId = warehouseInventory.getWarehouseId();
        Long customerId = warehouseInventory.getCustomerId();
        WarehouseDO warehouse = warehouseService.getWarehouse(warehouseId);
        AdminUserDO user = userService.getUser(customerId);
        String content= userService.getUser(loginUserId).getNickname()+"盘点"+user.getNickname()+warehouse.getName()+"库存内容:";
        List<WarehouseInventorySkuDO> warehouseInventorySkuList=warehouseInventorySkuService.getWarehouseInventorySkuList(warehouseId, customerId);
        content=content+warehouseInventorySkuList.stream().map(e->"长度:"+e.getLength()+",宽度:"+e.getWidth()+",高度:"+e.getHeight()+",重量:"+e.getWeight()+",库存:"+e.getNum()).collect(Collectors.joining(","));
        try {
        Long updateUser = erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(), content, getClass().getDeclaredMethod("updateUser", UserSaveReqVO.class));
        } catch (NoSuchMethodException e) {throw new RuntimeException(e);}});
        return success(true);
    }


}